﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;

namespace ImPM.Application
{
    public class ImPMLock : IDisposable
    {
        // Fields
        private bool disposed;
        private LockMode lockMode;
        private ReaderWriterLock rwLock;
        private int timeout;

        // Methods
        public ImPMLock(ReaderWriterLock rwLock, LockMode lockMode)
        {
            if (rwLock.IsReaderLockHeld || rwLock.IsWriterLockHeld)
            {
                string message = "Attempt to recursively acquire ReaderWriteLock";
                Trace.Assert(false, message);
                throw new ImPMException(message, -2147220933);
            }
            this.lockMode = lockMode;
            this.rwLock = rwLock;
            this.disposed = false;
            this.timeout = -1;
            switch (lockMode)
            {
                case LockMode.Read:
                    rwLock.AcquireReaderLock(this.timeout);
                    return;

                case LockMode.Write:
                    rwLock.AcquireWriterLock(this.timeout);
                    return;
            }
            throw new ImPMException(string.Format("Unexpected Lock Mode: {0}", lockMode), -2147220970);
        }

        public void Dispose()
        {
            this.Dispose(true);
        }

        public void Dispose(bool disposing)
        {
            if (!this.disposed && disposing)
            {
                GC.SuppressFinalize(this);
                if (this.rwLock.IsReaderLockHeld)
                {
                    this.rwLock.ReleaseReaderLock();
                }
                if (this.rwLock.IsWriterLockHeld)
                {
                    this.rwLock.ReleaseWriterLock();
                }
                this.disposed = true;
            }
        }

        ~ImPMLock()
        {
            this.Dispose(false);
        }
    }
}
